/**
 * @file factoryComm.h
 * @brief Libreria per gestire l'utilizzo dell'input-output dell'utente.
 *
 * Vengono documentate tutte le funzioni e le strutture dati necessarie per interagire
 * con l'output e l'input proveniente dall'interfaccia utente (non di rete).
 *
 * @date Mar 5, 2012
 * @author Francesco Corvino
 */

#ifndef FACTIORSC_H_
#define FACTIORSC_H_

#include "../utilities.h"
#include "session.h"
#include "../MemObj/cmap.h"

#define LOG_FACTORYCOMM_NAME "FactoryComm"

//////////////////////////////////////////////////////////////////////////////////////////
////// Strutture per permettere l'interfacciamento con delle Concrete Factory ////////////
//////////////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Struttura dati inserita per configurare le Concrete Factory per le sessioni.
 */
typedef struct ConfigurationComm_ {
	/**
	 * @brief funzione che permette al concrete factory di registrare nuove sessioni.
	 */
	void (*registerSession)(HostSession*);

	/**
	 * @brief funzione che permette al concrete factory di terminare delle sessioni.
	 */
	void (*closeSession)(HostSession*);
} ConfigurationComm;

/**
 * @brief La struttura indica cosa le concrete factory devono specificare.
 *
 * Le specifiche servono per completare tutte le funzionalità di comunicazione richieste.
 */
typedef struct ConcreteFactoryComm_ {
	// specifiche per l'instaurazione di nuove comunicazioni

	/**
	 * @brief specifica di avviare l'ascolto per nuove sessioni.
	 */
	void (*startListen)();

	/**
	 * @brief assegna la gestione di una sessione alla factory.
	 */
	void (*configure)(ConfigurationComm*);

	// specifiche per le comunicazioni di sessione

	/**
	 * @brief funzione che permette di restituire il file descriptor in lettura per la comunicazione.
	 */
	int (*getReadFD)(HiddenType*);

	/**
	 * @brief analogo di getReadFD per la scrittura.
	 */
	int (*getWriteFD)(HiddenType*);

	void (*close)(HiddenType*);
	void (*update)();
} ConcreteFactoryComm;

//////////////////////////////////////////////////////////////////////////////////////////
////// Struttura per definire le impostazioni della stessa Abstract Factory //////////////
//////////////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Struttura necessaria per definire le impostazioni sulle comunicazioni.
 *
 * Struttura per definire le impostazioni della stessa Abstract Factory
 */
typedef struct factoryComm {

	/**
	 * @brief indica se aggiungere la sessione da terminale dello stesso processo.
	 */
	char enableDefaultComm;

	/**
	 * @brief array dinamico delle concrete factory specificate per le comunicazioni.
	 */
	DynArray factories;
} FactoryComm;

//////////////////////////////////////////////////////////////////////////////////////////
////// Funzioni per inizializzare e avviare le configurazioni sulle comunicazioni ////////
//////////////////////////////////////////////////////////////////////////////////////////

void FactComm_init(FactoryComm * config);

void FactComm_start(FactoryComm * config);

HostSession * FactComm_getSession(int key);

HostSession * FactComm_getSessionFor(pthread_t tid);

void FactComm_deleteSession(HostSession * delSession);

CMap * FactComm_getSessions();

#endif /* FACTIORSC_H_ */
